import $ from "jquery";
class CaptchaConfig {
    constructor(args) {
        if (!args.bindEl) {
            throw new Error("[TAC] 必须配置 [bindEl]用于将验证码绑定到该元素上");
        }
        if (!args.requestCaptchaDataUrl) {
            throw new Error("[TAC] 必须配置 [requestCaptchaDataUrl]请求验证码接口");
        }
        if (!args.validCaptchaUrl) {
            throw new Error("[TAC] 必须配置 [validCaptchaUrl]验证验证码接口");
        }
        this.bindEl = args.bindEl;
        this.$bindEl = $(args.bindEl);
        this.requestCaptchaDataUrl = args.requestCaptchaDataUrl;
        this.validCaptchaUrl = args.validCaptchaUrl;
        if (args.validSuccess) {
            this.validSuccess = args.validSuccess;
        }
        if (args.validFail) {
            this.validFail = args.validFail;
        }
        if (args.requestHeaders) {
            this.requestHeaders = args.requestHeaders
        }else {
            this.requestHeaders = {}
        }
        this.requestChain = [];
        this.addRequestChainByString(args.chainString);
    }
    addRequestChainByString(chainString) {
        if (!chainString) {
            return
        }
        const chains = chainString.split(">")
        // 对chains字符串用>分隔
        for (const c of chains) {
            const chain = captchaRequestChains[c];
            if (chain) {
                this.addRequestChain(chain);
            }else {
                throw new Error(`[TAC] chains错误， 无法读取到[${c}]`);
            }
        }

    }
    addRequestChain(fun) {
        this.requestChain.push(fun);
    }

    requestCaptchaData() {
        const requestParam = {}
        requestParam.headers = this.requestHeaders;
        requestParam.data = {};
        // 请求前装载参数
        this._preRequest("requestCaptchaData", requestParam);
        // 发送请求
        const request = this.doSendRequest("requestCaptchaData", requestParam);
        // 返回结果
        return request.then(res => {
            // 装返回结果
            this._postRequest("requestCaptchaData", requestParam, res);
            // 返回结果
            return res;
        });
    }

    doSendRequest(type, requestParam) {
        let requestUrl;
        if (type === "requestCaptchaData") {
            requestUrl = this.requestCaptchaDataUrl;
        } else {
            requestUrl = this.validCaptchaUrl;
        }
        return new Promise((resolve, reject) => {
            $.ajax({
                url: requestUrl,
                type: "POST",
                headers: requestParam.headers,
                data: JSON.stringify(requestParam.data),
                dataType: "json",
                contentType:  "application/json;charset=UTF-8",
                success: (data) => {
                    resolve(data);
                },
                error: (err) => {
                    reject(err);
                }
            });
        });
    }

    _preRequest(type, requestParam, c, tac) {
        for (let i = 0; i < this.requestChain.length; i++) {
            const r = this.requestChain[i];
            if (r.preRequest) {
                if (!r.preRequest(type, requestParam, this, c, tac)) {
                    break;
                }
            }
        }

    }

    _postRequest(type, requestParam, res, c, tac) {
        for (let i = 0; i < this.requestChain.length; i++) {
            const r = this.requestChain[i];
            // 判断r是否存圩postRequest方法
            if (r.postRequest) {
                if (!r.postRequest(type, requestParam, res, this, c, tac)) {
                    break;
                }
            }
        }
    }

    validCaptcha(currentCaptchaId, data, c, tac) {
        const sendParam = {
            id: currentCaptchaId,
            data: data
        };
        this._preRequest("validCaptcha", sendParam, c, tac);
        const request = this.doSendRequest("validCaptcha", sendParam);
        return request.then(res => {
            this._postRequest("validCaptcha", sendParam, res, c, tac);
            return res;
        }).then(res => {
            if (res.code === 200) {
                const useTimes = (data.endSlidingTime - data.startSlidingTime) / 1000;
                c.showTips(`验证成功,耗时${useTimes}秒`, 1, () => this.validSuccess(res, c, tac));
            } else {
                let tipMsg = "验证失败，请重新尝试!";
                if (res.code) {
                    if (res.code !== 4001) {
                        tipMsg = "验证码被黑洞吸走了！";
                    }
                }
                c.showTips(tipMsg, 0, () => this.validFail(res, c, tac));
            }
        });
    }

    validSuccess(res, c, tac) {
        console.log("验证码校验成功， 请重写  [config.validSuccess] 方法， 用于自定义逻辑处理")
        window.currentCaptchaRes = res;
        tac.destroyWindow();
    }

    validFail(res, c, tac) {
        tac.reloadCaptcha();
    }
}

function wrapConfig(config) {
    if (config instanceof CaptchaConfig) {
        return config;
    }
    return new CaptchaConfig(config);
}

function wrapStyle(style) {
    if (!style) {
        style = {}
    }

    if (!style.btnUrl) {
        // 设置默认图片
        style.btnUrl = "";
    }
    if (!style.moveTrackMaskBgColor && !style.moveTrackMaskBorderColor) {
        style.moveTrackMaskBgColor = "#89d2ff";
        style.moveTrackMaskBorderColor = "#0298f8";

    }
    return style;
}

const captchaRequestChains = {}


export {CaptchaConfig, wrapConfig, wrapStyle}
